package cn.doourbest.learnnetty.learnnetty.util;

import cn.doourbest.learnnetty.learnnetty.pojo.HttpProxyServerConfig;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.HttpClientCodec;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

import java.util.HashMap;
import java.util.Map;


public class BSUtil {

    private static Bootstrap b = new Bootstrap();
    private static Bootstrap b1 = new Bootstrap();
    private static EventLoopGroup workerGroup = new NioEventLoopGroup();

    private static Map<Channel,Channel> map = new HashMap<>();

    public static void putMap(Channel key,Channel value){
        map.put(key,value);
    }

    public static Channel getMap(Channel key){
        return map.get(key);
    }

    static {
        b.group(workerGroup); // (2)
        b.channel(NioSocketChannel.class); // (3)
        b.option(ChannelOption.SO_KEEPALIVE, true); // (4)

        b1.group(workerGroup); // (2)
        b1.channel(NioSocketChannel.class); // (3)
        b1.option(ChannelOption.SO_KEEPALIVE, true); // (4)

    }

    public static Bootstrap getBootstrap(){
        b.handler(new ChannelInitializer<SocketChannel>() {
            @Override
            public void initChannel(SocketChannel ch) throws Exception {
                ch.pipeline().addLast(new HttpClientCodec());
                ch.pipeline().addLast(new BootstrapHandler());
            }
        });
        return b;
    }

    public static Bootstrap getHttpsBootStrap(HttpProxyServerConfig serverConfig,String host,int port){
        b.handler(new ChannelInitializer<SocketChannel>() {
            @Override
            public void initChannel(SocketChannel ch){
                ch.pipeline().addLast( serverConfig
                        .getClientSslCtx()
                        .newHandler(ch.alloc(), host, port));

                ch.pipeline().addLast(new HttpClientCodec());
                ch.pipeline().addLast(new BootstrapHandler());
            }
        });
        return b;
    }

    static class BootstrapHandler extends ChannelInboundHandlerAdapter {


        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
            System.out.println("代理到目标服务器的channel handler出错：");
            cause.printStackTrace();
        }

        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            Channel channel = ctx.channel();
            Channel value = getMap(ctx.channel());
            if(value != null){
                value.writeAndFlush(msg);
            }
        }

    }

}
